const connectBtn = document.getElementById('connectBtn')
const leaveBtn = document.getElementById('leaveBtn')
const userName = document.getElementById('userName')
const localVideo = document.getElementById('localVideo')
const remoteVideo = document.getElementById('remoteVideo')



const ROOM = '111';
let socket;

const mediaStreamConstrants = {
    video: true,
    audio: false
}

let localStream
let pc
let state = 'init'
let userMap;
let remoteStream

const offerOptions = {
    offerToReceiveAudio: false,
    offerToReceiveVideo: true
}

function sendMessage(message) {
    const user = userName.value
    console.log(`${user} send message:`);
    console.log(message);
    socket.emit("message", ROOM, user, message)
}

function createPeerConnection() {
    if (!pc) {
        pc = new RTCPeerConnection()
    }
    pc.onicecandidate = (e) => {
        console.log("=================== onicecandidate:");
        console.log(e.candidate);
        if (e.candidate) {
            sendMessage({
                type: 'candidate',
                label: e.candidate.sdpMLineIndex,
                id: e.candidate.sdpMid,
                candidate: e.candidate.candidate
            })
        }
    }
    pc.ontrack = (e) => {
        console.log("received remote video:");
        console.log(e);
        remoteStream = e.streams[0];
        remoteVideo.srcObject = e.streams[0];
    }
    localStream.getTracks().forEach(stream => {
        pc.addTrack(stream, localStream)
    });
}

function closePeerConnection() {
    if (!pc) {
        pc.close()
        pc = null
    }
}

function closeMediaStream() {
    if (localStream && localStream.getTracks()) {
        localStream.getTracks().forEach(stream => {
            stream.close()
        })
    }
    localStream = null
}

function conn() {
    const user = userName.value
    socket = io.connect('https://chris.mynatapp.cc/')
    // 进行事件监听
    socket.on("joined", (room, socketId, id) => {
        state = 'joined'
        console.log(`${id} join ${room}, current user:`);
        if (id === user) return;
        // 进行媒体协商
        createPeerConnection()
        // 创建信令
        pc.createOffer(offerOptions).then(desc => {
            pc.setLocalDescription(desc)
            sendMessage(desc)
        }).catch(err => console.error(err))
    })

    socket.on('userstatechange', (room, users) => {
        console.log('=================== userstatechange :');
        console.log(users);
        if (!userMap) {
            userMap = users
        }
        ////////////////////////
    })

    socket.on('message', (room, id, message) => {
        if (id === user || !message) return;
        console.log(`${user} get message from ${id}:`);
        console.log(message);
        if (message.type === 'offer') {
            createPeerConnection();
            pc.setRemoteDescription(new RTCSessionDescription(message))
            pc.createAnswer(offerOptions).then(desc => {
                pc.setLocalDescription(desc);
                sendMessage(desc)
            }).catch(err => console.error(err))

        } else if (message.type === 'answer') {
            pc.setRemoteDescription(new RTCSessionDescription(message))
        } else if (message.type === 'candidate') {
            const candidate = new RTCIceCandidate({
                candidate: message.candidate,
                sdpMLineIndex: message.label
            })
            pc.addIceCandidate(candidate)
        } else {

        }
    })

    socket.on('leave', (room, id) => {
        // 关闭其他人资源
        console.log(`${id} leave ${room}`);
    })
    socket.emit('join', ROOM, user)
}

function start() {
    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) return;
    navigator.mediaDevices.getUserMedia(mediaStreamConstrants).then(stream => {
        // 当前video设置流数据
        localVideo.srcObject = stream
        // 保存流数据
        localStream = stream
        // 建立连接
        conn()
    }).catch(err => {
        console.error(err)
    })
}


function leave() {
    if (socket) {
        const user = userName.value
        socket.emit('leave', ROOM, user);
        socket.disconnect()
        socket = null
    }
    closePeerConnection()
    closeMediaStream()
}


connectBtn.onclick = start
leaveBtn.onclick = leave

window.onbeforeunload = (e) => {
    leave()
    return true
}